'use strict';

const _ = require('lodash');
const utility = require('utility');
const validator = require('validator');
const Controller = require('egg').Controller;

class UserController extends Controller {

  async index() {
    const {ctx, service, config} = this;
    const user_name = ctx.params.name;
    const user = await service.userSvc.getUserByLoginName(user_name);
    if (!user) {
      ctx.status = 404;
      ctx.message = '这个用户不存在。';
      return;
    }

    if (this.ctx.user) {
      if (user.fans.map(v => v.name).includes(this.ctx.user.loginname)) {
        user.is_attention = true;
      } else {
        user.is_attention = false;
      }
    } else {
      user.is_attention = false;
    }

    let query = {author_id: user._id, tab: {'$ne': 'share'}};
    const opt = {limit: 5, sort: '-createdAt'};
    const [
      recent_topics, replies,
    ] = await Promise.all([
      service.topicSvc.getTopicsByQuery(query, opt),
      service.replySvc.getRepliesByAuthorId(user._id, {limit: 20, sort: '-updatedAt'}),
    ]);

    // 只显示最近5条
    const topic_ids = [...new Set(replies.map(reply => reply.topic_id.toString()))].slice(0, 5);

    query = {_id: {$in: topic_ids}};
    let recent_replies = await service.topicSvc.getTopicsByQuery(query, {});

    recent_replies = _.sortBy(recent_replies, topic => {
      return topic_ids.indexOf(topic._id.toString());
    });

    user.url = (() => {
      if (user.url && user.url.indexOf('http') !== 0) {
        return 'http://' + user.url;
      }
      return user.url;
    })();

    // 如果用户没有激活，那么管理员可以帮忙激活
    let token = '';
    if (!user.active && ctx.user && ctx.user.is_admin) {
      token = utility.md5(user.email + user.pass + config.session_secret);
    }


    const tag_name = ctx.request.query.tag_name;

    let locals = {
      user,
      recent_topics,
      recent_replies,
      token,
      pageTitle: `@${user.loginname} 的个人主页`,
      order_by: 'createdAt',
      tag_name
    };

    await ctx.renderX('user/index.nj', locals);
  }

  async listStars() {
    const {ctx, service} = this;
    const stars = await service.userSvc.getUsersByQuery({is_star: true}, {});
    await ctx.renderX('user/stars.nj', {stars});
  }

  async top100() {
    const {ctx, service} = this;
    const opt = {limit: 100, sort: '-score'};
    const tops = await service.userSvc.getUsersByQuery({is_block: false}, opt);
    await ctx.renderX('user/top100.nj', {
      users: tops,
      pageTitle: 'top100',
    });
  }


  async listReplies() {
    const {ctx, service} = this;
    const user_name = ctx.params.name;
    const current_page = Number(ctx.query.page) || 1;
    const limit = 50;

    const user = await service.userSvc.getUserByLoginName(user_name);
    if (!user) {
      ctx.status = 404;
      ctx.message = '这个用户不存在。';
      return;
    }

    const opt = {skip: (current_page - 1) * limit, limit, sort: '-createdAt'};
    const replies = await service.replySvc.getRepliesByAuthorId(user._id, opt);
    const topic_ids = [...new Set(replies.map(reply => {
      return reply.topic_id.toString();
    }))];
    // 获取所有有评论的主题
    const query = {_id: {$in: topic_ids}};
    let topics = await service.topicSvc.getTopicsByQuery(query, {});
    topics = _.sortBy(topics, topic => -topic.updatedAt);
    const count = await service.replySvc.getCountByAuthorId(user._id);
    const pages = Math.ceil(count / limit);

    const base_url = `/user/${user.loginname}/replies?page=`;
    const page_start = current_page - 5 > 0 ? current_page - 5 : 1;
    const page_end = page_start + 9 >= pages ? pages : page_start + 9;


    let locals = {
      user,
      topics,
      current_page,
      pages,
      base_url,
      page_start,
      page_end
    };

    await ctx.renderX('user/replies.nj', locals);
  }

  async showSetting() {
    const {ctx, service} = this;
    const id = ctx.user._id;
    const user = await service.userSvc.getUserById(id);
    user.ignore_users = user.ignore_users.join('\r\n');

    if (ctx.request.query.save === 'success') {
      user.success = '保存成功。';
    }

    return await ctx.renderX('user/setting.nj', {user, pageTitle: '设置'});
  }

  async setting() {
    const {ctx, service} = this;

    // 显示出错或成功信息
    async function showMessage(msg, data, isSuccess) {
      data = data || ctx.request.body;
      const user = {
        loginname: data.loginname,
        email: data.email,
        url: data.url,
        location: data.location,
        signature: data.signature,
        weibo: data.weibo,
        weixin: data.weixin,
        access_token: data.access_token,
        avatar_url: data.avatar_url,
        ignore_users: data.ignore_users,
      };

      if (isSuccess) {
        user.success = msg;
      } else {
        user.error = msg;
      }

      return await ctx.renderX('user/setting.nj', {user});
    }

    const action = ctx.request.body.action;
    if (action === 'change_setting') {
      let user = await service.userSvc.getUserById(ctx.user._id);

      // 用户的文章的冗余avatar都要更新
      if (user.avatar_url != ctx.request.body.avatar_url) {
        await ctx.model.Topic.updateMany({author_id: user.id}, {$set: {author_avatar: ctx.request.body.avatar_url}});
      }

      user = Object.assign(user, ctx.request.body);
      user.auto_tags = ctx.request.body.auto_tags.split('\r\n').filter(v => v).join('\r\n');
      user.ignore_users = ctx.request.body.ignore_users.split('\r\n').filter(v => v);
      await user.save();
      return ctx.redirect('/setting?save=success');
    }

    if (action === 'change_password') {
      const oldPass = validator.trim(ctx.request.body.old_pass);
      const newPass = validator.trim(ctx.request.body.new_pass);
      if (!oldPass || !newPass) {
        return showMessage('旧密码或新密码不得为空');
      }

      const user = await service.userSvc.getUserById(ctx.user._id);
      const equal = ctx.helper.bcompare(oldPass, user.pass);
      if (!equal) {
        return showMessage('当前密码不正确。', user);
      }

      const newPassHash = ctx.helper.bhash(newPass);
      user.pass = newPassHash;
      await user.save();
      return showMessage('密码修改成功。', user, true);
    }

  }


  async toggleStar() {
    const {ctx, service} = this;
    const user_id = ctx.request.body.user_id;

    const user = await service.userSvc.getUserById(user_id);
    user.is_star = !user.is_star;
    await user.save();
    ctx.body = {status: 'success'};
    return;
  }

  async block() {
    const {ctx, service} = this;
    const action = ctx.request.body.action;
    const loginname = ctx.params.name;
    const user = await service.userSvc.getUserByLoginName(loginname);

    if (action === 'set_block') {
      user.is_block = true;
      await user.save();
      ctx.body = {status: 'success'};
    } else if (action === 'cancel_block') {
      user.is_block = false;
      await user.save();
      ctx.body = {status: 'success'};
    }
  }

  async deleteAll() {
    const {ctx, service} = this;
    const loginname = ctx.params.name;
    const user = await service.userSvc.getUserByLoginName(loginname);

    // 删除主题
    await ctx.model.Topic.remove({author_id: user._id});
    // 删除评论
    await ctx.model.Reply.remove({author_id: user._id});
    // 点赞数也全部干掉
    await ctx.model.Reply.update({}, {$pull: {ups: user._id}}, {multi: true});
    ctx.body = {status: 'success'};
  }


  async listTopics() {
    const {ctx, service, config} = this;
    const user_name = ctx.params.name;
    const kw = ctx.request.query.kw || '';
    const tag_name = ctx.request.query.tag_name;
    const board_name = this.ctx.query.board_name || '全部';
    const current_page = Number(ctx.query.page) || 1;
    const page_size = config.list_topic_count;
    const ua = this.ctx.headers['user-agent'].toLocaleLowerCase();
    let pageTitle;


    let user;
    let user_id;

    try {
      user = await service.userSvc.getUserByLoginName(user_name);
      user_id = user._id;
    } catch (e) {
      // ctx.logger.warn('user_name:' + user_name, e.message);
    }
    let is_oneself;
    if (ctx.user && ctx.user.nickname == user_name) {
      pageTitle = '我的主页';
      is_oneself = true;
    } else {
      pageTitle = `${user_name}的主页`;
      is_oneself = false;
    }

    if (!user) {
      ctx.status = 404;
      ctx.message = '这个用户不存在。';
      return;
    }

    if (ctx.user) {
      await this.ctx.service.attentionSvc.updateLastVisit(ctx.user.id, user_name);
    }

    let count_original_topic;
    let topics;
    let pages;
    let my_original_tags;

    if (ctx.user && ctx.user.loginname == user_name) {
      [count_original_topic, topics, my_original_tags] = await Promise.all([
        service.topicSvc.countOriginalTopics(user_id, is_oneself, kw, tag_name, board_name),
        service.topicSvc.listOriginalTopics(user_id, is_oneself, kw, tag_name, current_page, page_size, board_name),
        service.topicSvc.listOriginalTags(user_id)
      ]);
    } else {
      [count_original_topic, topics] = await Promise.all([
        service.topicSvc.countOriginalTopics(user_id, is_oneself, kw, tag_name, board_name),
        service.topicSvc.listOriginalTopics(user_id, is_oneself, kw, tag_name, current_page, page_size, board_name),
      ]);
    }

    pages = Math.ceil(count_original_topic / page_size);

    topics.forEach(v => v.what_page = 'my_topics');

    for (const topic of topics) {
      if (!topic.pic) {
        topic.pic = topic.author_avatar;
      }
    }

    // 展示模式是丰富or精简
    if (this.ctx.user && this.ctx.user.view_type == 0) {
      for (const topic of topics) {
        delete topic['_doc']['intro'];
        delete topic['_doc']['pic'];
      }
    }


    let base_url = `/user/${user.loginname}?`;
    if (board_name) {
      base_url += `&board_name=${board_name}`;
    }
    if (tag_name) {
      base_url += `&tag_name=${tag_name}`;
    }
    if (kw) {
      base_url += `&kw=${kw}`;
    }
    base_url += '&page=';

    const page_start = current_page - 5 > 0 ? current_page - 5 : 1;
    const page_end = page_start + 9 >= pages ? pages : page_start + 9;


    // 增加board内容begin
    const user_boards = config.boards[user.loginname];
    let is_attention = false;
    if (this.ctx.user && this.ctx.user.followings.map(v => v.name).includes(user.loginname)) {
      is_attention = true;
    }
    // 增加board内容end


    for (const topic of topics) {
      if (!topic.pic) {
        topic.pic = topic.author_avatar;
      }
    }

    // 展示模式是丰富or精简
    if (this.ctx.user && this.ctx.user.view_type == 0) {
      for (const topic of topics) {
        delete topic['_doc']['intro'];
        delete topic['_doc']['pic'];
      }
    }


    let locals = {
      currentUser: this.ctx.user,
      is_attention,
      user,
      topics,
      current_page,
      tag_name,
      pages,
      kw,
      my_original_tags,
      order_by: 'createdAt',
      pageTitle,
      base_url,
      page_start,
      page_end,
      user_boards,
      board_name,
    };


    await ctx.renderX('user/topics.nj', locals);
  }


  async follow() {
    if (!this.ctx.user) {
      return this.ctx.body = {status: 'failed', msg: '未登录'};
    }
    let fan_name = this.ctx.user.loginname;
    let superstar_name = this.ctx.request.body.following_name;
    if (fan_name == superstar_name) {
      return this.ctx.body = {status: 'failed', msg: '不能订阅自己'};
    }

    await this.ctx.service.attentionSvc.follow(fan_name, superstar_name);
    this.ctx.body = {status: 'success', msg: '订阅成功'};
  }

  async unfollow() {
    if (!this.ctx.user) {
      return this.ctx.body = {status: 'not_login'};
    }
    await this.ctx.service.attentionSvc.unfollow(this.ctx.user.loginname, this.ctx.request.body.following_name);
    this.ctx.body = {status: 'success', msg: '取消订阅成功'};
  }

  async listAttentions() {
    let kw = this.ctx.query.kw || '';
    const user_name = this.ctx.params.name;
    const current_page = parseInt(this.ctx.query.page) || 1;
    const page_size = 1000;

    let user = await this.service.userSvc.getUserByLoginName(user_name);

    let [[users, count], followingUnreadTopicInfoList] = await Promise.all([
      this.ctx.service.attentionSvc.listFollowings(user.loginname, current_page, page_size),
      this.ctx.service.attentionSvc.getUnreadFollowingsInfo(user)
    ]);

    let pages = Math.ceil(count / page_size);
    let superstar_names = followingUnreadTopicInfoList.map(v => v.name);

    users = _.sortBy(users, v => {
      return superstar_names.indexOf(v.loginname);
    });

    if (this.ctx.user && this.ctx.user.loginname == user_name) {
      for (let search_user of users) {
        for (let followingUnreadTopicInfo of followingUnreadTopicInfoList) {
          if (followingUnreadTopicInfo.name == search_user.loginname) {
            search_user.unread = followingUnreadTopicInfo.unread;
            break;
          }
        }
      }
    }

    // 如果用户已登录, 则判断当前用户的关注列表中有没有查询结果item, 如果有的话, 则is_attention设为true
    if (this.ctx.user) {
      for (let search_user of users) {
        if (this.ctx.user.followings.map(v => v.name).includes(search_user.loginname)) {
          search_user.is_attention = true;
        } else {
          search_user.is_attention = false;
        }
      }
    } else { // 如果用户未登录, 则所有item的is_attention都设为false
      for (let search_user of users) {
        search_user.is_attention = false;
      }
    }

    const base_url = `/${user_name}/attentions&page=`;

    let locals = {
      kw,
      user,
      data: users,
      current_page,
      count,
      pages,
      attentionsOrFans: '订阅',
      base_url
    }

    let url;
    const ua = this.ctx.headers['user-agent'].toLocaleLowerCase();
    if (ua.includes('iphone') || ua.includes('ipad') || ua.includes('android')) {
      url = 'user/attentions_mobile.nj';
    } else {
      url = 'user/attentions.nj';
    }

    return await this.ctx.renderX(url, locals);
  }


  async listFans() {
    let kw = this.ctx.query.kw || '';
    let user_name = this.ctx.params.name;
    if (user_name == '殷海翔') {
      user_name = 'yinhaixiang';
    }
    const current_page = parseInt(this.ctx.query.page) || 1;
    const page_size = 1000;

    let user = await this.service.userSvc.getUserByLoginName(user_name);
    let [users, count] = await this.ctx.service.attentionSvc.listFans(user.loginname, current_page, page_size);
    let pages = Math.ceil(count / page_size);

    users.sort((a, b) => {
      return user.fans.indexOf(a.loginname) - user.fans.indexOf(b.loginname);
    });


    // 如果用户已登录, 则判断当前用户的关注列表中有没有查询结果item, 如果有的话, 则is_attention设为true
    if (this.ctx.user) {
      for (let search_user of users) {
        if (this.ctx.user.followings.map(v => v.name).includes(search_user.loginname)) {
          search_user.is_attention = true;
        } else {
          search_user.is_attention = false;
        }
      }
    } else { // 如果用户未登录, 则所有item的is_attention都设为false
      for (let search_user of users) {
        search_user.is_attention = false;
      }
    }

    const base_url = `/${user_name}/fans&page=`;

    let locals = {
      kw,
      user,
      data: users,
      current_page,
      count,
      pages,
      attentionsOrFans: '粉丝',
      base_url
    }

    let url;
    const ua = this.ctx.headers['user-agent'].toLocaleLowerCase();
    if (ua.includes('iphone') || ua.includes('ipad') || ua.includes('android')) {
      url = 'user/attentions_mobile.nj';
    } else {
      url = 'user/attentions.nj';
    }

    return await this.ctx.renderX(url, locals);
  }


  async alluser() {
    const current_page = +this.ctx.query.page || 1;
    let kw = this.ctx.query.kw || '';
    let page_size = 60;

    let [data, count] = await this.ctx.service.searchSvc.searchUser(kw, current_page, page_size);
    let pages = Math.ceil(count / page_size);

    const page_start = current_page - 5 > 0 ? current_page - 5 : 1;
    const page_end = page_start + 9 >= pages ? pages : page_start + 9;


    let result = {
      kw,
      data,
      current_page,
      pages,
      count,
      page_start,
      page_end,
      base_url: `/user_square?kw=${kw}&page=`,
    };

    const ua = this.ctx.headers['user-agent'].toLocaleLowerCase();
    if (ua.includes('iphone') || ua.includes('ipad') || ua.includes('android')) {
      return await this.ctx.renderX('user/alluser_mobile.nj', result);
    } else {
      return await this.ctx.renderX('user/alluser.nj', result);
    }
  }


  async toggleViewType() {
    let view_type = this.ctx.request.body.view_type;
    view_type = view_type == 'true' ? 0 : 1;
    const user = await this.service.userSvc.getUserById(this.ctx.user._id);
    user.view_type = view_type;
    await user.save();

    this.ctx.body = {status: 'success'};
  }

  async hasUnreadTopic(ctx) {
    if (!ctx.user) {
      return ctx.ok({hasUnreadTopic: false});
    }
    const hasUnreadTopic = await ctx.service.attentionSvc.hasUnreadTopic(ctx.user);
    ctx.ok({hasUnreadTopic});
  }


}

module.exports = UserController;
